package com.dxf.hchat.netty;

import com.alibaba.fastjson.JSON;

import com.dxf.hchat.pojo.TbChatRecord;

import com.dxf.hchat.service.ChatRecordService;
import com.dxf.hchat.utils.SpringUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * 处理消息的handler
 * TextWebSocketFrame: 在netty中，是用于为websocket专门处理文本的对象，frame是消息的载体
 */
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    //用来保存所有的客户端连接
    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd hh:MM:ss");


    /**
     * 当channel中有新的事件消息会自动调用
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //当接受到数据后会自动调用
        String text = msg.text();
        System.out.println("接收到的数据为: " + text);
       /* for (Channel client : clients) {
            //将消息发送到所有客户端
            client.writeAndFlush(new TextWebSocketFrame(sdf.format(new Date())+text));
        }*/

        Message message = JSON.parseObject(text, Message.class);
        //根据spring工具类从容器中获取ChatRecordService实例
        ChatRecordService chatRecordService = SpringUtil.getBean(ChatRecordService.class);

        switch (message.getType()) {
            case 0:
                //建立用户与通道的关联
                String userid = message.getChatRecord().getUserid();
                UserChannelMap.put(userid, ctx.channel());
                UserChannelMap.print();

                break;
            case 1:
                System.out.println("接收到用户消息");
                //处理客户端发送好友消息

                TbChatRecord chatRecord = message.getChatRecord();//聊天记录

                //0 把数据保存到数据库中
                chatRecordService.insert(chatRecord);

                Channel channel = UserChannelMap.get(chatRecord.getFriendid());//得到通道
                if (channel!=null){
                    //1 如果好友在线,直接发送给好友
                    channel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(message)));


                }else {
                    System.out.println("用户"+chatRecord.getFriendid()+"不在线");
                }

                //2 如果不在线,暂时不发送

                break;
            case 2://签收,如果聊天窗口打开着,在收到消息时,把消息改为已读

                chatRecordService.updateStatusHasRead(message.getChatRecord().getId());

                break;
            case 3:
                break;
            case 4:
                break;

        }


    }

    /**
     * 当有新的客户端连接服务器后,会自动调用这个方法
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        //当有新的连接(handler)加入时,会自动调用这个方法

        //将新的通道加入到clients中
        clients.add(ctx.channel());
    }


    /**
     * 出现异常
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        UserChannelMap.removeByChannelId(ctx.channel().id().asLongText());
        ctx.channel().close();

    }

    /**
     * 客户端连接断开
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("关闭通道");
        UserChannelMap.removeByChannelId(ctx.channel().id().asLongText());
        UserChannelMap.print();
    }
}
